/**
 * 
 */
package com.netflexitysolutions.amazonws.sdb.orm;

import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;

import com.netflexitysolutions.amazonws.sdb.Domain;
import com.netflexitysolutions.amazonws.sdb.orm.filter.Predicate;
import com.netflexitysolutions.amazonws.sdb.orm.metadata.ItemMetadata;

/**
 * @author netflexity
 *
 */
public interface SimpleDBSession {

	/**
	 * @return the factory
	 */
	public SimpleDBSessionFactory getFactory();
	
	/**
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	public <T>ItemMetadata getMetadata(Class<T> clazz);
	
	/**
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	public <T>String getDomainName(Class<T> clazz);
	
	/**
	 * Gets the Amazon SDB Domain by class.
	 * 
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	public <T> Domain getDomain(Class<T> clazz);
	
	/**
	 * @param domainName
	 * @return
	 */
	public Domain getDomain(String domainName);
	
	/**
	 * @param <T>
	 * @param record
	 */
	public <T> void populate(T record);
	
	/**
	 * @param <T>
	 * @param record
	 * @return
	 */
	public <T> Object getId(T record);
	
	/**
	 * Finds an object by id.
	 * 
	 * @param <T>
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T> T find(Class<T> clazz, String id);
	
	/**
	 * @param <T>
	 * @param clazz
	 * @param orderBy
	 * @return
	 */
	public <T> Set<T> findAll(Class<T> clazz, String ... orderBy);
	
	/**
	 * @param <T>
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T> Future<T> findAsync(Class<T> clazz, String id);
	
	/**
	 * @param <T>
	 * @param clazz
	 * @param orderBy
	 * @return
	 */
	public <T> Future<Set<T>> findAllAsync(Class<T> clazz, String ... orderBy);
	
	/**
	 * @param <T>
	 * @param query
	 * @param paramName
	 * @param paramValue
	 * @return
	 */
	public <T> List<T> find(String query, String paramName, Object paramValue);
	
	/**
	 * @param <T>
	 * @param query
	 * @param paramNames
	 * @param paramValues
	 * @return
	 */
	public <T> List<T> find(String query, String[] paramNames, Object[] paramValues);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @param orderBy
	 * @return
	 */
	public <T> List<T> select(Predicate<T> predicate, String ... orderBy);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @param orderBy
	 * @return
	 */
	public <T> Future<List<T>> selectAsync(Predicate<T> predicate, String ... orderBy);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> Integer count(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> Future<Integer> countAsync(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> int min(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> Future<Integer> minAsync(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> int max(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> Future<Integer> maxAsync(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> int avg(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param predicate
	 * @return
	 */
	public <T> Future<Integer> avgAsync(Predicate<T> predicate);
	
	/**
	 * @param <T>
	 * @param object
	 */
	public <T> void save(T object);
	
	/**
	 * @param <T>
	 * @param object
	 * @return
	 */
	public <T>Future<T> saveAsync(T object);
	
	/**
	 * @param <T>
	 * @param object
	 */
	public <T> void remove(T object);
	
	
	/**
	 * @param <T>
	 * @param clazz
	 * @param id
	 */
	public <T> void remove(Class<T> clazz, String id);
	
	/**
	 * @param <T>
	 * @param record
	 * @return
	 */
	public <T> Future<Void> removeAsync(T record);
	
	/**
	 * @param <T>
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T> Future<Void> removeAsync(Class<T> clazz, String id);
	
	/**
     * @param <T>
     * @param clazz
     * @param id
     * @return
     */
    public <T> T cacheGet(Class<T> clazz, String id);
    
    /**
     * @param <T>
     * @param clazz
     * @return
     */
    public <T> List<T> cacheGetAll(Class<T> clazz);
    
    /**
     * @param <T>
     * @param record
     */
    public <T> void cachePut(T record);
    
    /**
     * @param <T>
     * @param clazz
     * @param id
     */
    public <T> void cacheRemove(Class<T> clazz, String id);
}
